package org.bt.common.validator.size;

import org.bt.common.validator.aspect.Size;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.invoke.MethodHandles;

/**
 * Check that the length of an array is between <i>min</i> and <i>max</i>
 *
 * @author tongw
 */
public class SizeValidatorForArray implements ConstraintValidator<Size, Object[]> {

    private static final Log LOG = LoggerFactory.make(MethodHandles.lookup());

    private int min;
    private int max;

    @Override
    public void initialize(Size parameters) {
        min = parameters.min();
        max = parameters.max();
        validateParameters();
    }

    /**
     * Checks the number of entries in an array.
     *
     * @param array                      The array to validate.
     * @param constraintValidatorContext context in which the constraint is evaluated.
     * @return Returns {@code true} if the array is {@code null} or the number of entries in
     * {@code array} is between the specified {@code min} and {@code max} values (inclusive),
     * {@code false} otherwise.
     */
    @Override
    public boolean isValid(Object[] array, ConstraintValidatorContext constraintValidatorContext) {
        if (array == null) {
            return true;
        }
        return array.length >= min && array.length <= max;
    }

    private void validateParameters() {
        if (min < 0) {
            throw LOG.getMinCannotBeNegativeException();
        }
        if (max < 0) {
            throw LOG.getMaxCannotBeNegativeException();
        }
        if (max < min) {
            throw LOG.getLengthCannotBeNegativeException();
        }
    }
}
